﻿
#include "AirManager.h"

FlipFlag operator|(const FlipFlag &a, const FlipFlag &b)
{
    int result = int(a) | int(b);
    return FlipFlag(result);
}

int getdata(std::vector<std::string> &temp, const std::string &tempbuf, unsigned int first = 0)  //,��؂�̃f�[�^�����I�[�����s�ł���Ƃ����O��
{
    unsigned int index1 = first;
    unsigned int length = tempbuf.length();
    for (;;) {

        unsigned int index2 = tempbuf.find_first_of(",\n", index1);
        std::string data("");
        for (unsigned int j = index1; j < index2; j++) {
            if ((tempbuf[j] == ' ') || (tempbuf[j] == '\t'))
                continue;
            data += tempbuf[j];
        }
        temp.push_back(data);
        index1 = index2 + 1;
        if (index1 >= length)
            break;
    }

    return 0;
}

void stringRemoveChar(std::string &string, char c)
{
    while(1) {
        size_t pos = string.find_first_of(c);
        if (pos == std::string::npos) {
            break;
        }
        string.erase(pos, 1);
    }
}

bool stringIsAllChar(const std::string &string, char c)
{
    for (const char cTmp : string) {
        if (cTmp != c) {
            return false;
        }
    }
    return true;
}


int SAnim::Dec(FILE *&fp)
{
    char digit[] = "-0123456789";
    bool defaultclsnflag = false;//true�Ȃ��,clsn��default���ɓ����B����Default�ɉ�Ό���defaultclsn��clsn1,clsn2��clsnnum�Ŏw�肳�ꂽ��������������,true�ɂȂ�@default�̒�`�łȂ��Ƃ�false�ɂȂ�
    bool usedefaultflag1 = true;//true�Ȃ�΁Aframe������Ƃ�default���g���BDefault�łȂ�Clsn�̒�`�ɉ��false����āAdefault�łȂ�Clsn������frame�������Ƃ�true�����
    bool usedefaultflag2 = true;
    int clsnnum = 0;
    bool nextloop = false;//true�Ȃ玟�̃t���[����loop��true�ɂ���

    SFrame nowframe;
    SFrame defaultclsn;
    while (1) {
        std::string buf("");
        {
            char temp;
            do {
                temp = fgetc(fp);
                buf += temp;
            } while ((temp != '\n') && (temp != EOF));
        }

        if (buf.find_first_of(";") != std::string::npos)
            buf.erase(buf.find_first_of(";"));

        buf.erase(buf.find_last_not_of(" \t\n;") + 1);//�I�[�������s��
        buf += '\n';

        if ((buf.find("LoopStart") != std::string::npos) || (buf.find("Loopstart") != std::string::npos)
                || (buf.find("loopStart") != std::string::npos) || (buf.find("loopstart") != std::string::npos)) {//loopstart
            nextloop = true;
            defaultclsnflag = false;
            usedefaultflag1 = true;
            usedefaultflag2 = true;
            continue;
        }

        // 忽略 Interpolate Scale 参数
        if ((buf.find("Interpolate Scale") != std::string::npos)) {
            continue;
        }

        if (buf.find_first_of(digit) == std::string::npos) {//�������S�������ĂȂ����
            break;
        }

        if ((buf.find("Clsn", 0) != std::string::npos)) {//Clsn�̕���������ꍇ
            if (buf.find(":") != std::string::npos) {//clsn�̒�`
                unsigned int index1 = buf.find_first_of(digit);
                clsnnum = buf[index1] - '0';//Clsn?:

                if (buf.find("Default") != std::string::npos) {//Default�Ȃ��
                    if (clsnnum == 1)
                        defaultclsn.Clsn1 = std::vector<Coordinate::SCoordinate>();
                    else if (clsnnum == 2)
                        defaultclsn.Clsn2 = std::vector<Coordinate::SCoordinate>();
                    defaultclsnflag = true;
                } else {
                    if (clsnnum == 1) {
                        usedefaultflag1 = false;
                    }
                    if (clsnnum == 2) {
                        usedefaultflag2 = false;
                    }
                    defaultclsnflag = false;
                }
                continue;
            } else { //���ۂ�clsn���W
                Coordinate::SCoordinate tempCoordinate;
                std::vector<std::string>data;
                unsigned int first = buf.find("=") + 1;
                getdata(data, buf, first);
                for (int i = 0; i < 4; i++)
                    tempCoordinate.coordinate[i] = atoi(data[i].c_str());

                Coordinate::SCoordinate::diagonalchange(tempCoordinate.coordinate);

                if (clsnnum == 1) {
                    if (defaultclsnflag == true) {
                        defaultclsn.Clsn1.push_back(tempCoordinate);
                    } else nowframe.Clsn1.push_back(tempCoordinate);
                } else if (clsnnum == 2) {
                    if (defaultclsnflag == true) {
                        defaultclsn.Clsn2.push_back(tempCoordinate);
                    } else nowframe.Clsn2.push_back(tempCoordinate);
                } else return -2; //***********************************************
                continue;
            }
        }
        //frame����
        SFrame data;

        if (usedefaultflag1 == true) {
            data.Clsn1 = defaultclsn.Clsn1;
        } else {
            data.Clsn1 = nowframe.Clsn1;
            usedefaultflag1 = true;
            nowframe.Clsn1 = std::vector<Coordinate::SCoordinate>();
        }
        if (usedefaultflag2 == true) {
            data.Clsn2 = defaultclsn.Clsn2;
        } else {
            data.Clsn2 = nowframe.Clsn2;
            usedefaultflag2 = true;
            nowframe.Clsn2 = std::vector<Coordinate::SCoordinate>();
        }
        std::vector<std::string> framedata;
        getdata(framedata, buf);

        switch (framedata.size()) {
        case 10:
        // 旋转角度
        case 9:
        // x y缩放率
        case 7: {
            std::size_t it;
            if ((it = framedata[6].find("AS")) != std::string::npos) {
                data.AS = std::stoi(std::string{ framedata[6].begin() + it + 2, framedata[6].end() });
                data.layer = 1;
            } else if (framedata[6].find("A") != std::string::npos) {
                data.layer = 1;
            } else if (framedata[6].find("S") != std::string::npos) {
                data.layer = 2;
            }
            if ((it = framedata[6].find("D")) != std::string::npos) {
                data.D = std::stoi(std::string{ framedata[6].begin() + it + 1, framedata[6].end() });
                data.layer = 1;
            }
        }
        case 6: {
            if (framedata[5].find("H") != std::string::npos)
                data.FlipF = data.FlipF | FlipFlag::Horizontal;
            if (framedata[5].find("V") != std::string::npos)
                data.FlipF = data.FlipF | FlipFlag::Vertical;
        }
        case 5: {
            data.Group = atoi(framedata[0].c_str());
            data.Image = atoi(framedata[1].c_str());
            data.Delay = atoi(framedata[4].c_str()); break;
        }
        default: return -3;//*******************************************
        }

        if (nextloop == true) {
            loop = m_frameVector.size();//���̎��_�ō��������悤�Ƃ���SFrame��,Anim�̂O���琔����vector�C���f�b�N�X�Ԗڂ������[�v�̍ŏ��ƂȂ�
            nextloop = false;
        }
        m_frameVector.push_back(data);
    }

    return 0;

}

int AirManager::DecAir(const char *filename)
{
    m_actionVector.clear();
    FILE *fp;
    if ((fp = fopen(filename, "r")) == NULL)
        return -1;

    const char digit[] = "-0123456789";
    std::string name;
    while (1) {
        std::string buf("");
        {
            char temp;
            do {
                temp = fgetc(fp);
                buf += temp;
            } while ((temp != '\n') && (temp != EOF));
        }

        size_t commentCharPos = buf.find_first_of(";");
        if (commentCharPos != std::string::npos) {
            std::string comment = buf;
            comment.erase(commentCharPos, 1);
            comment.erase(comment.find_first_of("\n"));
            comment.erase(comment.find_first_of("\r"));

            if (!stringIsAllChar(comment, '-')
                && !stringIsAllChar(comment, '='))
            {
                name += comment;
            }

            buf.erase(buf.find_first_of(";"));
        }

        buf.erase(buf.find_last_not_of(" \t\n;") + 1);//�I�[�������s��
        buf += '\n';

        if (buf[0] == EOF)
            break;

        int actionnum = -1;
        if (buf.find("[") != std::string::npos) {
            unsigned int index1 = buf.find_first_of(digit);
            unsigned int index2 = buf.find_first_not_of(digit, index1);
            std::string num("");
            for (unsigned int i = index1; i < index2; i++)
                num += buf[i];
            actionnum = atoi(num.c_str());

            SAnim Anim;
            int Decerror = 0;
            if ((Decerror = Anim.Dec(fp)) < 0) {
                fclose(fp);
                return Decerror;
            }

            Action a;
            a.Name = name;
            name.clear();
            a.Id = actionnum;
            a.Ani = Anim;
            m_actionVector.push_back(a);
        }
    }
    fclose(fp);
    return 0;
}
